package com.ultisense.gassensor;

import android.util.Log;

import java.util.Random;

public class SourceCalculation {

    //presetting
    double L = 2;//long side length of sensors
    double W = 2;//short side length of sensors;
    double speed_h2 = 0.01;//propagation speed of hydrogen m/s

    //axis from screen (set from source Fragment)
    //relative axis (0,0) (L,0) (L,W) (0,W)
    int x1, y1, x2, y2, x3, y3, x4, y4;//axis of nodes on the screen, x1,y1 as original point
    double xToAxis, yToAxis;

    public void axisChange() {
        xToAxis = (x2 - x1) / L;
        yToAxis = (y4 - y1) / W;
    }

    public void setAxis(int[] location1, int[] location2, int[] location3, int[] location4) {
        this.x1 = location1[0];
        this.y1 = location1[1];
        this.x2 = location2[0];
        this.y2 = location2[1];
        this.x3 = location3[0];
        this.y3 = location3[1];
        this.x4 = location4[0];
        this.y4 = location4[1];
        axisChange();
    }

    //time (set from sourceFragment)
    Long flagTime[]=new Long[4];
    public void getFlagTime(long sensorTime,int nodeNumber){
        this.flagTime[nodeNumber-1]=sensorTime+syncSensorTime[nodeNumber-1];
    }

    Long[] syncSensorTime = new Long[4];
    //sync time of each node
    public void syncTime(int sensorNum, long equipTime, long appTime) {
        syncSensorTime[sensorNum-1] = timeSync(equipTime, appTime);
    }

    //distance from source to sensor
    double l1, l2, l3, l4;
    //delta distance
    double d_l2, d_l3, d_l4;
    //relative position of source
    double r_x, r_y;

    public double getDeltaDistance(double t1, double t2, double speed_h2) {
        double delta = (t2 - t1) * speed_h2;
        return delta;
    }

    public void getDelta() {
        d_l2 =getDeltaDistance(flagTime[0],flagTime[1],speed_h2);
        d_l3 =getDeltaDistance(flagTime[0],flagTime[2],speed_h2);
        d_l4 =getDeltaDistance(flagTime[0],flagTime[3],speed_h2);
    }

    public long timeSync(long equipTime,long appTime){
        long syncTime;
        long commDelay=5;//set delay of time
        syncTime=appTime-commDelay-equipTime;
        return syncTime;
    }


    //Axis position of node
    int x_position;
    int y_position;

    public void calculation() {
        if (!flagTime[0].equals(null)&&!flagTime[1].equals(null)&&!flagTime[2].equals(null)&&!flagTime[3].equals(null)){
            Log.i("position","successfully start positioning");
            getDelta();
            l1 = (d_l4 * d_l4 - d_l3 * d_l3 - d_l2 * d_l2) / (2 * d_l2 + 2 * d_l3 - 2 * d_l4);
            r_x = (L * L - 2 * l1 * d_l2 - d_l2 * d_l2) / (2 * L);
            r_y = (W * W - 2 * l1 * d_l3 - d_l3 * d_l3) / (2 * W);
            x_position = x1 + (int) (r_x * xToAxis);
            y_position = y1 + (int) (r_y * yToAxis);}
            else if (d_l4==0 && d_l3==0 && d_l2==0)
            {
                r_x = L/2;
                r_y = W/2;
                x_position = x1 + (int) (r_x * xToAxis);
                y_position = y1 + (int) (r_y * yToAxis);
            }
            else if (d_l4==0 && d_l3!=0 && d_l2!=0)
            {
                r_x =(-(4*L*Math.pow(d_l2,2)-4*Math.pow(L,3))+ Math.sqrt(16*Math.pow(L,2)*Math.pow(d_l2,2)*Math.pow(W,2)+16*Math.pow(d_l2,6)+16*Math.pow(d_l2,2)*Math.pow(L,4)-32*Math.pow(L,2)*Math.pow(d_l2,4)-16*Math.pow(W,2)*Math.pow(d_l2,4))) /2*(4*Math.pow(L,2)-4*Math.pow(d_l2,2));
                r_y = W/2;
                x_position = x1 + (int) (r_x * xToAxis);
                y_position = y1 + (int) (r_y * yToAxis);
            }
            else if (d_l2==0 && d_l3 != 0 && d_l4!=0)
            {
                r_y =(-(4*W*Math.pow(d_l3,2)-4*Math.pow(W,3))+ Math.sqrt(16*Math.pow(W,2)*Math.pow(d_l3,2)*Math.pow(L,2)+16*Math.pow(d_l3,6)+16*Math.pow(d_l3,2)*Math.pow(W,4)-32*Math.pow(W,2)*Math.pow(d_l3,4)-16*Math.pow(W,2)*Math.pow(d_l3,4))) /2*(4*Math.pow(W,2)-4*Math.pow(d_l3,2));
                r_x = L/2;
                x_position = x1 + (int) (r_x * xToAxis);
                y_position = y1 + (int) (r_y * yToAxis);
            }

        else {
            Log.e("position","no enough data");
        }

    }

    public int getX_position() {
        return x_position;
    }

    public int getY_position() {
        return y_position;
    }
}
